package com.artisan.web.action;

/**
 * Created by yang on 2017/6/18.
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.artisan.common.pojo.ApiRes;
import com.artisan.common.pojo.Constant;
import com.artisan.common.utils.DateTimeUtils;
import com.artisan.common.utils.Utils;
import com.artisan.common.utils.wxpay.*;
import com.artisan.medium.wx.pojo.AccessToken;
import com.artisan.medium.wx.service.WxAddressService;
import com.artisan.medium.wx.service.WxBusinessService;
import com.artisan.medium.wx.service.WxUserService;
import com.artisan.medium.wx.utils.AccessTokenUtils;
import com.artisan.model.*;
import com.artisan.web.pojo.OrderInfoMapping;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

@Controller
@RequestMapping("/wx/business/")
public class WxBusiessController {
    @Autowired
    private WxBusinessService wxBusinessService;

    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private WxAddressService wxAddressService;

    private static final Logger logger = LogManager.getLogger(WxBusiessController.class);


    @RequestMapping("homePage")
    public ModelAndView homePage(HttpServletRequest request, HttpServletResponse response){
        Map<String,Object> map=wxBusinessService.qService();
        return new ModelAndView("/index",map);
    }

    /**
     * 通过2级业务类型 获取3级业务类型
     * @param  request
     * @param  response
     * @return
     */
    @RequestMapping("getBusinessbyId")
    public ModelAndView getBussinessbyId(HttpServletRequest request, HttpServletResponse response){
        int bid=Integer.valueOf(String.valueOf(request.getParameter("bid")));
        Map<String,Object> map=new HashMap<String,Object>();
        List<Business> business = wxBusinessService.qServices(bid);
        map.put("business",business);
        return new ModelAndView("/order_select",map);
    }


    @RequestMapping("toOrderPage")
    public ModelAndView toOrderPage(HttpServletRequest request, HttpServletResponse response){
        int bid=Integer.valueOf(String.valueOf(request.getParameter("bid")));
        Map<String,Object> map=new HashMap<String,Object>();
        Customer customer=null;
        System.out.println("toOrderPage方法:USER内置session值="+request.getSession().getAttribute("TOKEN"));

        Map<String, Object> resultData = new HashMap<String, Object>();
        String code = request.getParameter("code");
        logger.info("code:[" + code + "]");
        AccessToken at=null;
        if(request.getSession().getAttribute("TOKEN")!=null){
            at=(AccessToken) request.getSession().getAttribute("TOKEN");
        }else{
            at = AccessTokenUtils.getAccessTokenUtil(code);
            request.getSession().setAttribute("TOKEN",at);
        }
        String openid = at.getOpenid();
        resultData.put("openid", openid);

        customer=wxUserService.getCustomerByOpenId(openid);
        if(customer==null){
            map.put("openid",openid);
            return new ModelAndView("/my_reg",map);
        }else{
            Business bus = wxBusinessService.qService(bid);
            Address address=wxAddressService.getAddressDefault(customer.getId());
            //合计费用
            List<Business>business=new ArrayList<Business>();
            business.add(bus);
            map.put("business",business);
            map.put("customer",customer);
            map.put("sumprice",bus.getPrice());
            map.put("openid",openid);
            map.put("address",address);
            return new ModelAndView("/order_confirm",map);
        }

    }

    /**
     * 提交订单
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "saveOrder",method = RequestMethod.GET)
    public String saveOrder(OrderInfoMapping  mapper, HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<String, Object>();
        String openid = String.valueOf(request.getParameter("openid"));
        Customer customer = wxUserService.getCustomerByOpenId(openid);
        if (customer == null) {
            map.put("result", ApiRes.USER_OUTTIME_CODE);
            return JSON.toJSONString(map);
        } else {
            //provinceId  cityId  areaId
            String[] ads = mapper.getCitys().split(" ");
            String provinceId = null;
            String cityId = null;
            String areaId = null;
            for (int i = 0; i < ads.length; i++) {
                if (i == 0) {
                    provinceId = wxAddressService.getAddIdByName(ads[i]);
                } else if (i == 1) {
                    cityId = wxAddressService.getAddIdByName(ads[i]);
                } else {
                    ads[i] = ads[i].replace("区", "");
                    areaId = wxAddressService.getAddIdByName(ads[i]);
                }
            }
            System.out.println(provinceId);
            System.out.println(cityId);
            System.out.println(areaId);

            Address address = new Address();
            address.setAphone(mapper.getPhone());
            address.setAname(mapper.getAddress());
            address.setDefaultAddress(false);
            address.setAddress(mapper.getAddDetail());
            address.setuName(mapper.getUname());
            address.setCitys(mapper.getCitys());
            address.setuId(customer.getId());
            address.setProvinceId(provinceId);
            address.setCityId(cityId);
            address.setAreaId(areaId);
            String addressId=request.getParameter("addressId");
            if(addressId==null){
                int aId = wxAddressService.addAddress(address);
                address.setId(aId);
            }else{
                address.setId(Integer.valueOf(addressId));
                wxAddressService.addAddress(address);
                wxAddressService.defaultAddress(address.getId(),customer.getId());
            }

            //保存订单业务
            CustomerOrderinfo order = new CustomerOrderinfo();
            String order_no = Utils.getOutTradeNo();
            order.setOrderNo(order_no);
            order.setUserId(customer.getId());
            order.setBids(mapper.getBids());
            System.out.println(DateTimeUtils.strToDate(mapper.getServiceTime(), Constant.TIME_FOMART));
            order.setServiceTime(DateTimeUtils.strToDate(mapper.getServiceTime(), Constant.TIME_FOMART));
            order.setMoney(mapper.getMoney());
            order.setMessage(mapper.getMessage());
            order.setIsdelete(false);
            order.setaId(address.getId());
            wxBusinessService.addOrder(order);
            map.put("result", ApiRes.SUCCESS_CODE);
            map.put("trade_no",order.getOrderNo());
            return JSON.toJSONString(map);
        }
    }

    @ResponseBody
    @RequestMapping(value = "depositweixin",method = RequestMethod.POST)
    public Map<String, Object> doSaveApply(HttpServletRequest request, HttpServletResponse response)
    {
        String openid=request.getParameter("openid");
        if(openid==null){
            if(request.getSession().getAttribute("TOKEN")!=null){
                AccessToken at=(AccessToken) request.getSession().getAttribute("TOKEN");
                openid=at.getOpenid();
            }
        }
        String total_fee =request.getParameter("money");
        String trade_no =request.getParameter("trade_no");
        logger.info("方法depositweixin.do=openid:"+openid);
        Map<String, Object> data = new HashMap<String, Object>();
        //todo 是否支付验证
        Map<String, String> signMap = new HashMap<String, String>();
        //订单名称
        String bName = request.getParameter("bName");
        //付款金额
        if(total_fee.indexOf(".")>-1){
            total_fee=(Double.parseDouble(total_fee)*100+"").split("\\.")[0];
        }else{
            total_fee=Integer.parseInt(total_fee)*100+"";
        }
        try {
            Map<String, String> map = new HashMap<String, String>();
            String ip=request.getRemoteAddr();
            WXGZHParInfo wxgzhParInfo=WXGZHParInfo.createPayInfo(total_fee,ip,trade_no);
            String device_info="10000";
            String subject = trade_no;
            logger.info("subject:[" + subject + "]");
            long timestamp = System.currentTimeMillis() / 1000;
            map.put("appid", wxgzhParInfo.getAppid());
            map.put("mch_id", wxgzhParInfo.getMch_id()); // 商户号
            map.put("nonce_str", wxgzhParInfo.getNonce_str()); // 随机字符串
            map.put("body", subject);
            map.put("out_trade_no",wxgzhParInfo.getOut_trade_no()); // 时间戳
            map.put("total_fee", total_fee); // 总价
            map.put("spbill_create_ip", wxgzhParInfo.getSpbill_create_ip());
            map.put("notify_url", wxgzhParInfo.getNotify_url());
            map.put("trade_type", wxgzhParInfo.getTrade_type());
            /*map.put("product_id",product_id);//商品编号*/
            wxgzhParInfo.setOpenid(openid);
            map.put("openid", openid);
            map.put("device_info", device_info);
            String paySign = SignUtil.getPayCustomSign(map, PayConfig.WeixinGZHPayConfig.KEY);
            map.put("sign",paySign);
            String xml = WxXmlUtil.ArrayToXml(map);
            String prepayid = getPrepayid(xml);
            if(prepayid==null){
                data.put("result", ApiRes.ERROR_CODE);
                data.put("msg", "参数配置有误");
                return data;
            }
            logger.info("prepareid*****************************=" + prepayid);
            logger.error("》》》》》》》》》》》》》》》发起微信支付时产生的订单号："+map.get("out_trade_no"));
            signMap.put("appId", wxgzhParInfo.getAppid());
            signMap.put("packageValue", "prepay_id=" + prepayid);
            signMap.put("nonceStr", wxgzhParInfo.getNonce_str());
            signMap.put("signType", "MD5");
            signMap.put("timeStamp", timestamp + "");
            String paySign2 = SignUtil.getPayCustomSign2(signMap, PayConfig.WeixinGZHPayConfig.KEY);
            signMap.put("paySign", paySign2);
            System.out.println(ApiRes.SUCCESS_CODE);
            data.put("result", ApiRes.SUCCESS_CODE);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("result", ApiRes.ERROR_CODE);

        }
        data.putAll(signMap);
        return data;
    }

    @RequestMapping(value = "returnUrl")
    public String  weixinNotify(HttpServletRequest request,
                                HttpServletResponse response) throws JDOMException {
        System.out.println("wx pay is return join");
        Map<String,Integer>requelstMap=new HashMap<String,Integer>();
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String resultStr = new String(outSteam.toByteArray(), "utf-8");
            Map<String, String> resultMap = XMLUtil.doXMLParse(resultStr);
            String order_no = resultMap.get("out_trade_no");
            String trade_no =resultMap.get("transaction_id");
            String return_code =resultMap.get("return_code");
            String total_fee=resultMap.get("total_fee");//支付金额
            System.out.println("----------------"+return_code);
            System.out.println("check is hava trade_no ?");
            if(wxBusinessService.getPayInfo(trade_no)!=null){
                System.out.println(":HAVE");
                return "SUCCESS";
            }
            System.out.println("return_code.equals(SUCCESS)="+return_code.equals("SUCCESS")+":update record start");
            if(return_code.equals("SUCCESS")){

                try {
                    System.out.println("trade_no:"+trade_no);
                    CustomerPayinfo payinfo=new CustomerPayinfo();
                    payinfo.setPrice(new BigDecimal(total_fee));
                    payinfo.setTradeNo(trade_no);
                    payinfo.setOrderNo(order_no);
                    payinfo.setState(0);
                    payinfo.setType(1);
                    wxBusinessService.savePayInfo(payinfo);
                    wxBusinessService.updateOrderState(order_no);
                    //更改订单状态
                }catch (Exception e){
                    System.out.println("insert payInfo errer:"+e);
                }
                System.out.println("update record end");
            }
            request.setAttribute("out_trade_no", order_no);
            response.getWriter().write("SUCCESS");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }

    public  String getPrepayid(String xml){
        try {
            JSONObject jo=getPrepayJson(xml);
            JSONObject element=jo.getJSONObject("xml");
            String prepayid=((JSONArray)element.get("prepay_id")).get(0).toString();
            return prepayid;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String URL="https://api.mch.weixin.qq.com/pay/unifiedorder";
    @SuppressWarnings("deprecation")
    public JSONObject getPrepayJson(String xml){
        HttpClient httpClient = new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true) );
        InputStream is = null;
        PostMethod method=null;
        try {
            String url =URL;
            method = HttpClientUtils.postMethod(url);
            method.setRequestBody(xml);
            httpClient.executeMethod(method);
            //读取响应
            is = method.getResponseBodyAsStream();
            JSONObject o = Xml2JsonUtil.xml2JSON(is);
            return o;
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(method!=null){
                method.releaseConnection();
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return null;
    }
}
